package com.cskaoyan.javase.oop1._13block._1building._0introduction;

/**
 * 什么是构造代码块 ？
 * 定义在类的成员位置，使用以下声明方式声明的代码块，称之为构造代码块。
 * //成员位置
 * {
 * }
 * //成员位置
 *
 * 作用:
 * 构造代码块随着构造器的执行而执行,它的作用和构造器的作用是一致的
 * 都是在new对象过程中,用于给成员变量赋值,可以认为它是构造器赋值的补充.
 * 构造代码块中同样隐含this传参,指向当前对象
 *
 * 总结到目前位置,new对象过程中,成员变量的赋值:
 *      1.默认初始化
 *      2.显式赋值
 *      3.构造器赋值
 *      4.构造代码块赋值
 * "掐头去尾" 默认初始化最先执行,构造器赋值最后执行
 * 显式赋值和构造代码块赋值,放在中间执行,而且是按照代码书写顺序,从上到下执行
 * 以上就是构造代码块最基本的使用
 *
 * 接下来思考一下原理:
 * 查看反编译后的类字节码文件,是不存在构造代码块的结构的
 * 构造代码块中代码会加到构造器中去执行
 *
 * 反编译后的代码中并不存在构造代码块的结构，而是：
 * 直接将成员变量的显式赋值和构造代码块中的代码智能地加入，类所有的构造器中的前几行：
 *  所谓智能是为了保证:
 *  成员变量的显式赋值和构造代码块，按照代码的书写顺序从上到下执行！
 *  之所以要加在前几行:
 *      是为了保证构造代码块中的代码,在构造器代码之前执行
 *
 *  构造代码块中的代码最终会加入到类的所有构造器中,所以只要new对象,构造代码块一定会执行(不管用类的哪个构造器)
 *  当然如果是首行存在this调用其它构造器的构造器,就不需要将构造代码块中的代码加入了.
 *
 * @since 17:18
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // System.out.println(s.age);
        new Student(19);
    }
}

class Student {

    int age = 18;
    String name = "张三";

    // 构造代码块
    {
        System.out.println("Student构造代码块执行!");
        age = 28;
    }

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    public Student(int age, String name) {
        this(age);
        this.name = name;
    }
}